package org.jsea.meta.api.service;

import lombok.Setter;
import org.jsea.meta.api.bean.MetaApiDefinitionBean;
import org.jsea.meta.api.bean.MetaApiField;
import org.jsea.meta.api.service.dialect.IMetaApiDialect;

import java.util.List;
import java.util.StringJoiner;

/**
 * --.
 * *
 * author   Jiang.hy
 * create   2022-04-09
 */
public class MetaApiQueryHandler extends AbstractMetaApiHandler {

    @Setter
    protected IMetaApiDialect dialect;//数据库方言
    private final MetaApiProperties.Query query;

    public MetaApiQueryHandler(MetaApiDefinitionBean bean, MetaApiProperties.Query query) {
        super(bean);
        this.query = query;
    }

    @Override
    public String sql() {
        StringJoiner sql = new StringJoiner(" ");
        sql.add("select")
                .add(columns())
                .add("from")
                .add(table());
        String where = getWhere();
        if (where != null) {
            sql.add(where);
        }
        String order = orderBy();
        if (order != null) {
            sql.add(order);
        }
        if (bean.getId() == null) {
            return (limit(sql.toString()));
        }
        return sql.toString();
    }

    public String countSql() {
        StringJoiner sql = new StringJoiner(" ");
        sql.add("select count(1)")
                .add("from")
                .add(table());
        String where = getWhere();
        if (where != null) {
            sql.add(where);
        }
        return sql.toString();
    }

    protected String columns() {
        List<MetaApiField> column = bean.getColumn();
        if (column == null || column.isEmpty()) {
            return "*";
        }
        if (column.size() == 1) {
            MetaApiField next = column.getFirst();
            return next.getName() + (next.getAlias() == null ? "" : " as \"" + next.getAlias() + "\"");
        }
        StringJoiner columns = new StringJoiner(", ");
        for (MetaApiField tf : column) {
            String alias = tf.getAlias();
            if (alias == null) {
                columns.add(tf.getName());
            } else {
                columns.add(tf.getName() + " as \"" + tf.getAlias() + "\"");
            }
        }
        return columns.toString();
    }

    protected String limit(String sql) {
        Integer size = bean.getSize();
        if (size == null || size < 1) {
            size = bean.getRelations() == null ? query.getLimitDef() : query.getLimitMax();
        }
        Integer page = bean.getPage();
        if (page == null) {
            page = 1;
        }
        int limit = Math.min(size, query.getLimitMax());
        return dialect.buildPaginationSql(sql, limit * (page - 1), limit);
    }
}
